<script setup lang="ts">
  import { computed, CSSProperties, ref, watch } from 'vue'
  import { Loading } from '@element-plus/icons-vue'
  import { PropType } from 'vue'

  const props = defineProps({
    loading: {
      type: Boolean,
      default: () => false,
    },
    type: {
      type: String as PropType<'default' | 'primary' | 'success' | 'warning' | 'error'>,
      default: () => 'default',
    },
    width: Number,
    height: Number,
    disabled: {
      type: Boolean,
      default: () => false,
    },
    paddingLr: {
      type: Number,
      default: () => 10,
    },
    isModal: {
      type: Boolean,
      default: () => false,
    },
    paddingLeft: Number,
    paddingRight: Number,
    contentStyle: {
      type: Object as PropType<CSSProperties>,
      default: () => null,
    },
  })

  // 加载
  const btnLoading = ref(false)

  // 按钮的禁用状态
  const btnDisabled = ref(false)

  // 按钮类型
  const buttonType = ref<'default' | 'primary' | 'success' | 'warning' | 'error'>('default')

  // 按钮容器样式
  const hButtonDivStyle = computed(() => {
    if (props.isModal) {
      return 'height: 30px; padding: 0 16px;'
    }
    return `height: ${props.height || 28}px; width: ${
      props.width ? `${props.width}px` : 'fit-content'
    }; padding: 0 ${props.paddingRight || props.paddingLr}px 0 ${
      props.paddingLeft || props.paddingLr
    }px;`
  })

  // 按钮容器类名
  const HButtonClass = computed(() => {
    let result: string = buttonType.value

    if (props.disabled || props.loading) {
      result = `${buttonType.value}_disabled`
    }

    return result
  })

  // 按钮取消聚焦事件
  const onCancelFocus = (e: Event) => {
    ;(e.target as HTMLButtonElement).blur()
  }

  watch(
    props,
    (value) => {
      if (typeof value.loading === 'boolean') {
        btnLoading.value = value.loading
      }

      if (typeof value.disabled === 'boolean') {
        btnDisabled.value = value.disabled
      }

      if (['default', 'primary', 'success', 'warning', 'error'].includes(value.type)) {
        buttonType.value = value.type
      }
    },
    { immediate: true },
  )
</script>

<template>
  <el-button
    :disabled="btnDisabled"
    class="h_button"
    :loading="loading"
    :style="hButtonDivStyle"
    :class="HButtonClass"
    @focus="onCancelFocus"
  >
    <div class="content" :style="props.contentStyle || ''">
      <slot></slot>
    </div>

    <template #loading>
      <el-icon class="loading_icon" :color="buttonType === 'default' ? '#909399' : '#fff'">
        <Loading />
      </el-icon>
    </template>
  </el-button>
</template>

<style scoped lang="scss">
  .h_button {
    border-radius: 2px;
    border-color: #dcdfe6;
    margin: 0 !important;

    .content {
      display: flex;
      gap: 5px;
      align-items: center;
      color: #666;
    }
  }

  .loading_icon {
    animation: loading-rotate 2s linear infinite;
  }

  .default:hover {
    border-color: rgba($primaryColor, 0.2);
    background-color: rgba($primaryColor, 0.1);

    .content {
      color: rgba($primaryColor, 0.8) !important;
    }
  }

  .default_disabled {
    border-color: #ebeef5;
    background-color: #fff;

    .content {
      color: #c0c4cc !important;
    }

    &:hover {
      border-color: #ebeef5;
      background-color: #fff;
    }
  }

  .primary {
    background-color: $primaryColor;
    border-color: $primaryColor;

    .content {
      color: #fff;
    }

    &:hover {
      background-color: rgba($primaryColor, 0.6);
      border-color: rgba($primaryColor, 0);
    }
  }

  .primary_disabled {
    background-color: rgba($primaryColor, 0.4) !important;
    border-color: rgba($primaryColor, 0) !important;

    .content {
      color: #fff;
    }

    &:hover {
      background-color: rgba($primaryColor, 0.4);
      border-color: rgba($primaryColor, 0);
    }
  }

  .success {
    border-color: $secondColor3 !important;
    background-color: $secondColor3 !important;

    .content {
      color: #fff;
    }

    &:hover {
      background-color: rgba($secondColor3, 0.6);
      border-color: rgba($secondColor3, 0);
    }
  }

  .success_disabled {
    background-color: rgba($secondColor3, 0.4) !important;
    border-color: rgba($secondColor3, 0) !important;

    .content {
      color: #fff;
    }

    &:hover {
      background-color: rgba($secondColor3, 0.4);
      border-color: rgba($secondColor3, 0);
    }
  }

  .error {
    border-color: $deleteColor !important;
    background-color: $deleteColor !important;

    .content {
      color: #fff;
    }

    &:hover {
      border-color: rgba($deleteColor, 0);
      background-color: rgba($deleteColor, 0.6);
    }
  }

  .error_disabled {
    border-color: rgba($deleteColor, 0);
    background-color: rgba($deleteColor, 0.4);

    .content {
      color: #fff;
    }

    &:hover {
      border-color: rgba($deleteColor, 0);
      background-color: rgba($deleteColor, 0.4);
    }
  }

  .warning {
    border-color: $secondColor2;
    background-color: $secondColor2;

    .content {
      color: #fff;
    }

    &:hover {
      border-color: rgba($secondColor2, 0);
      background-color: rgba($secondColor2, 0.6);
    }
  }

  .warning_disabled {
    border-color: rgba($secondColor2, 0);
    background-color: rgba($secondColor2, 0.4);

    .content {
      color: #fff;
    }

    &:hover {
      border-color: rgba($secondColor2, 0);
      background-color: rgba($secondColor2, 0.4);
    }
  }
</style>
